from django.db import models, transaction
from django.utils.translation import gettext, gettext_lazy as _
from django.core.exceptions import ValidationError

from apps.app_service.models import OrgDataCenter, DataCenter
from utils.model import get_encryptor, UuidModel
from utils.validators import http_url_validator


class AIHubService(UuidModel):
    """
    AIHub服务单元
    """
    class Status(models.TextChoices):
        ENABLE = 'enable', _('服务中')
        DISABLE = 'disable', _('停止服务')
        DELETED = 'deleted', _('删除')

    org_data_center = models.ForeignKey(
        to=OrgDataCenter, null=True, on_delete=models.SET_NULL, related_name='+', verbose_name=_('云节点'),
        db_constraint=False, blank=True, default=None)
    name = models.CharField(max_length=255, verbose_name=_('服务名称'))
    name_en = models.CharField(verbose_name=_('服务英文名称'), max_length=255, default='')
    endpoint_url = models.CharField(
        max_length=255, verbose_name=_('服务地址url'), help_text='http(s)://{hostname}:{port}/')
    username = models.CharField(
        max_length=128, verbose_name=_('用户名'), blank=True, default='', help_text=_('用于此服务认证的用户名'))
    password = models.CharField(max_length=255, verbose_name=_('密码'), blank=True, default='')
    creation = models.DateTimeField(verbose_name=_('创建时间'), auto_now_add=True)
    modification = models.DateTimeField(verbose_name=_('修改时间'), auto_now=True)
    status = models.CharField(
        verbose_name=_('服务状态'), max_length=32, choices=Status.choices, default=Status.ENABLE.value)
    contact_person = models.CharField(verbose_name=_('联系人'), max_length=128, blank=True, default='')
    contact_email = models.EmailField(verbose_name=_('联系人邮箱'), blank=True, default='')
    contact_telephone = models.CharField(verbose_name=_('联系人电话'), max_length=16, blank=True, default='')
    contact_fixed_phone = models.CharField(verbose_name=_('联系人固定电话'), max_length=16, blank=True, default='')
    contact_address = models.CharField(verbose_name=_('联系人地址'), max_length=256, blank=True, default='')
    longitude = models.FloatField(verbose_name=_('经度'), blank=True, default=0)
    latitude = models.FloatField(verbose_name=_('纬度'), blank=True, default=0)
    sort_weight = models.IntegerField(verbose_name=_('排序值'), default=0, help_text=_('值越小排序越靠前'))
    version = models.CharField(max_length=32, blank=True, default='', verbose_name=_('版本号'), help_text=_('服务当前的版本'))
    version_update_time = models.DateTimeField(verbose_name=_('版本号更新时间'), null=True, blank=True, default=None)
    remarks = models.CharField(max_length=255, default='', blank=True, verbose_name=_('备注'))

    class Meta:
        db_table = 'ai_aihub_service'
        ordering = ['sort_weight']
        verbose_name = _('AIHub服务单元')
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
        super().save(force_insert=force_insert, force_update=force_update,
                     using=using, update_fields=update_fields)

    def _name_with_odc_name(self):
        if self.org_data_center:
            return f'{self.org_data_center.name}【{self.name}】'

        return self.name

    def _name_en_with_odc_name(self):
        if self.org_data_center:
            return f'{self.org_data_center.name_en}[{self.name_en}]'

        return self.name_en

    def clean(self):
        # 网址验证
        try:
            http_url_validator(self.endpoint_url)
        except ValidationError:
            raise ValidationError(message={'endpoint_url': gettext('不是一个有效的网址')})

    def raw_password(self):
        """
        :return:
            str     # success
            None    # failed, invalid encrypted password
        """
        encryptor = get_encryptor()
        try:
            return encryptor.decrypt(self.password)
        except encryptor.InvalidEncrypted as e:
            return None

    def set_password(self, raw_password: str):
        encryptor = get_encryptor()
        self.password = encryptor.encrypt(raw_password)
